package api

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"path"
	"path/filepath"
	"server/internal/app/model"
	"server/internal/app/serv"
	"server/internal/database"
	"server/internal/pkg/response"
	"server/pkg/tools"
	"strconv"
	"strings"
	"time"
)

var Common = new(common)

type common struct{}
type List struct {
	Label string `json:"label" gorm:"column:name"`
	Value int    `json:"value" gorm:"column:id"`
}

func (common) Area(ctx *gin.Context) {
	Db := database.DB
	province := ctx.Query("province")
	city := ctx.Query("city")
	pid := "0"
	if province != "" {
		pid = province
	}
	if city != "" {
		pid = city
	}

	table := model.Area{}
	var list []List
	Db.Model(&table).Where("pid = ?", pid).Find(&list)
	ctx.JSON(200, gin.H{"code": 0, "msg": "ok", "data": list})
}

func (common) Upload(ctx *gin.Context) {
	// 获取文件(注意这个地方的file要和html模板中的name一致)
	file, err := ctx.FormFile("file")
	if err != nil {
		//fmt.Println("获取数据失败")
		response.Fail(ctx, "", err.Error())
		return
	} else {
		//获取文件名称
		//fmt.Println(file.Filename)

		//文件大小
		//fmt.Println(file.Size)
		var size int64 = 2 //文件大小限制 MB
		if file.Size/1024/1024 > size {
			response.Fail(ctx, "", "图片大小不能超过2MB")
			return
		}
		//获取文件的后缀名
		extString := path.Ext(file.Filename)
		//fmt.Println(extstring)
		//根据当前时间鹾生成一个新的文件名
		fileNameInt := time.Now().Unix()
		fileNameStr := strconv.FormatInt(fileNameInt, 10)
		//新的文件名
		fileName := fileNameStr + extString
		//保存上传文件
		filePath := filepath.Join(tools.Mkdir("public/upload"), "/", fileName)
		err = ctx.SaveUploadedFile(file, filePath)
		if err != nil {
			response.Fail(ctx, "", err.Error())
			return
		}

		filePath = strings.Replace(filePath, string(filepath.Separator), "/", -1)
		response.Success(ctx, filePath, "文件上传成功")
	}
}

// Query 查询构造
func (common) Query(db *gorm.DB, c *gin.Context) *gorm.DB {
	tissueId := ""
	search := c.QueryArray("search[]")
	for _, v := range search {
		//json转map
		maps := make(map[string]interface{})
		json.Unmarshal([]byte(v), &maps)
		var field string
		if maps["tableName"] != nil {
			field = maps["tableName"].(string) + "." + maps["field"].(string)
		} else {
			field = maps["field"].(string)
		}

		if field == "contains" {
			continue
		}

		val, _ := tools.CheckType(maps["val"])

		operator := maps["operator"].(string)

		if field == "tissue_id" {
			tissueId = val
			if isContains(search) {
				id, _ := strconv.Atoi(val)
				ids := serv.Tissue.GetTissueIds(id, []int{})
				db = db.Where(field+" in ?", ids)
				continue
			}
		}

		if field != "" && val != "" {
			switch operator {
			case "LIKE":
				db = db.Where(field+" LIKE ?", "%"+val+"%")
			case "RANGE":
				arr := strings.Split(val, ",")
				if maps["render"] == "datetime" {
					loc, _ := time.LoadLocation("Local")
					startTime, _ := time.ParseInLocation("2006-01-02 15:04:05", arr[0], loc)
					endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", arr[1], loc)
					db = db.Where(field+" between ? and ?", startTime.Unix(), endTime.Unix())
				} else {
					db = db.Where(field+" between ? and ?", arr[0], arr[1])
				}

			case "FIND_IN_SET":
				db = db.Where("find_in_set(?,"+field+")", val)
			case "TEXT_ARR":
				vals := strings.Split(val, "\n")
				db = db.Where(field+" in ?", vals)

			//case "REGEXP":
			//	val = getDepartmentIds(val, 0)
			//	val = strings.Replace(val, ",", "|", -1)
			//	db = db.Where("CONCAT (','," + field + ",',') REGEXP ',(" + val + "),'")

			default:
				db = db.Where(field+" "+operator+" ?", val)
			}

		}

	}

	paths := c.Request.URL.Path
	paths = strings.Trim(paths, "/")
	//企业信息 企业信息审核列表 用户列表
	if paths == "enterprise/enterprise_update/list" || paths == "enterprise/enterprise/list" || paths == "system/sys_user/list" {
		rules, _ := c.Get("rules")
		userInfo, _ := c.Get("userInfo")
		rulesString := rules.(string)
		//不是超级管理员 或者筛选条件的 组织id没穿 ，只查看当前组织下数据
		if rulesString != "*" && tissueId == "" {

			db = db.Where("tissue_id=?", userInfo.(model.User).TissueId)
		}

	}

	//企业信息 企业信息审核列表
	if paths == "enterprise/enterprise_update/list" || paths == "enterprise/enterprise/list" {
		userInfo, _ := c.Get("userInfo")
		//如果是网格员 之查看自己的数据
		if userInfo.(model.User).GroupId == 3 {
			db = db.Where("user_id=?", userInfo.(model.User).ID)
		}
	}

	order := c.Query("order")
	if order == "" {
		//db = db.Order("id desc")
	} else {
		arr := strings.Split(order, ",")
		db = db.Order(arr[0] + " " + arr[1])
	}

	return db
}

// Paging 分页
func (common) Paging(db *gorm.DB, c *gin.Context) *gorm.DB {
	page, _ := strconv.Atoi(c.Query("page"))
	pageTotal, _ := strconv.Atoi(c.Query("limit"))
	if page == 0 {
		page = 1
	}
	if pageTotal == 0 {
		pageTotal = 10
	}
	db = db.Limit(pageTotal).Offset((page - 1) * pageTotal)

	return db
}

func isContains(s []string) bool {
	for _, v := range s {
		//json转map
		maps := make(map[string]interface{})
		json.Unmarshal([]byte(v), &maps)
		var field string
		field = maps["field"].(string)
		if field == "contains" {
			if maps["val"].(string) == "1" {
				return true
			} else {
				return false
			}
			break
		}

	}
	return false
}

// Daping 数据大屏
func (common) Daping(ctx *gin.Context) {
	Db := database.DB
	data := make(map[string]any)

	tissueName := tissueNameArr()

	var userTotal int64 //用户总数
	Db.Table("user").Count(&userTotal)

	var userList []model.User //用户总数
	Db.Table("user").Order("id desc").Limit(20).Find(&userList)

	var result []struct { //根据组织统计
		TissueId   int
		TissueName string
		Count      int
	}
	Db.Raw("SELECT tissue_id, COUNT(*) AS count FROM `user` where tissue_id >0 GROUP BY tissue_id").Scan(&result)
	for k, v := range result {
		result[k].TissueName = tissueName[v.TissueId]

	}

	var userTodayTotal int64 //今天注册的用户
	Db.Table("user").Where("DATE(FROM_UNIXTIME(create_time))=CURDATE()").Count(&userTodayTotal)
	data["user"] = map[string]any{ //用户
		"total":      userTotal,
		"todayTotal": userTodayTotal,
		"list":       userList,
		"iissueList": result,
	}

	var enterpriseTotal int64 //企业信息总数
	Db.Table("enterprise").Count(&enterpriseTotal)

	var enterpriseTodayTotal int64 //今天企业信息
	Db.Table("enterprise").Where("DATE(FROM_UNIXTIME(create_time))=CURDATE()").Count(&enterpriseTodayTotal)

	var enterpriseList []model.Enterprise //企业信息总数
	Db.Table("enterprise").Order("id desc").Limit(20).Find(&enterpriseList)

	var result2 []struct { //根据组织统计
		TissueId   int
		TissueName string
		Count      int
	}
	Db.Raw("SELECT tissue_id, COUNT(*) AS count FROM `enterprise` where tissue_id >0 GROUP BY tissue_id").Scan(&result2)
	for k, v := range result2 {
		result2[k].TissueName = tissueName[v.TissueId]

	}
	data["enterprise"] = map[string]any{
		"total":      enterpriseTotal,
		"todayTotal": enterpriseTodayTotal,
		"list":       enterpriseList,
		"tissueList": result2,
	}
	response.Success(ctx, data, "ok")
}

func tissueNameArr() map[int]string {
	Db := database.DB
	var result []struct { //根据组织统计
		Id   int
		Name string
	}
	Db.Table("tissue").Find(&result)

	arr := make(map[int]string)
	for _, v := range result {
		arr[v.Id] = v.Name
	}

	return arr
}

// 数据大屏
// 用户
func (common) Zuo1(ctx *gin.Context) {
	Db := database.DB
	data := make(map[string]any)

	var userTotal int64 //用户总数
	Db.Table("user").Count(&userTotal)

	var userTodayTotal int64 //今天注册的用户
	Db.Table("user").Where("DATE(FROM_UNIXTIME(create_time))=CURDATE()").Count(&userTodayTotal)
	data["total"] = userTotal
	data["todayTotal"] = userTodayTotal

	response.Success(ctx, data, "ok")
}

func (common) Zuo2(ctx *gin.Context) {
	Db := database.DB

	var result []struct { //根据组织统计
		Id       int
		Name     string
		Count    int
		CityCode int `json:"city_code"`
	}
	Db.Table("tissue").
		Select("tissue.id,tissue.`name`,(select count(*) from `user` where `city` like CONCAT('黑龙江省-', tissue.`name`,'%')) as count").
		Where("level=?", 2).
		Find(&result)

	response.Success(ctx, result, "ok")
}

func (common) Zuo3(ctx *gin.Context) {
	Db := database.DB

	var result []struct {
		Name       string `json:"name"`
		CreateTime int    `json:"create_time"`
		City       string `json:"city"`
		GroupId    string `json:"group_id"`
	}
	Db.Table("user").
		Select("name,create_time,city,group_id").
		Order("id desc").
		Limit(20).Find(&result)

	response.Success(ctx, result, "ok")
}

// 企业信息
func (common) You1(ctx *gin.Context) {
	Db := database.DB
	data := make(map[string]any)

	var userTotal int64 //总数
	Db.Table("enterprise").Count(&userTotal)

	var userTodayTotal int64 //今天的
	Db.Table("enterprise").Where("DATE(FROM_UNIXTIME(create_time))=CURDATE()").Count(&userTodayTotal)

	var isMember int64 //总数
	Db.Table("enterprise").Where("is_member=?", 1).Count(&isMember)

	data["total"] = userTotal
	data["todayTotal"] = userTodayTotal
	data["yesMember"] = isMember
	data["noMember"] = userTotal - isMember
	response.Success(ctx, data, "ok")
}

func (common) You2(ctx *gin.Context) {
	Db := database.DB

	var result []struct { //根据组织统计
		Id       int
		Name     string
		Count    int
		CityCode int    `json:"city_code"`
		Lng      string `json:"lng"`
		Lat      string `json:"lat"`
	}
	Db.Table("tissue").
		Select("tissue.*,(select count(*) from `enterprise` where `city` like CONCAT('黑龙江省-', tissue.name,'%')) as count").
		Where("level=?", 2).
		Find(&result)

	response.Success(ctx, result, "ok")
}

func (common) You3(ctx *gin.Context) {
	Db := database.DB

	var result []struct {
		UnitName   string `json:"name"`
		CreateTime int    `json:"create_time"`
		City       string `json:"city"`
		IsMember   string `json:"is_member"`
	}
	Db.Table("enterprise").Order("id desc").Limit(20).Find(&result)

	response.Success(ctx, result, "ok")
}

func (common) Zhong2(ctx *gin.Context) {
	Db := database.DB

	var result []struct { //根据组织统计
		Id        int
		Name      string
		UserCount int
		ECount    int
	}
	Db.Table("tissue").
		Select("tissue.*,"+
			"(select count(*) from `enterprise` where `city` like CONCAT('黑龙江省-', tissue.name,'%')) as user_count,"+
			"(select count(*) from `user` where `city` like CONCAT('黑龙江省-', tissue.name,'%')) as e_count").
		Where("level=?", 2).
		Find(&result)

	var rateData []int
	var barData []int
	var category []string
	for _, v := range result {
		rateData = append(rateData, v.ECount)
		barData = append(barData, v.UserCount)
		category = append(category, v.Name)
	}
	data := make(map[string]any)
	data["rateData"] = rateData
	data["barData"] = barData
	data["category"] = category
	response.Success(ctx, data, "ok")
}
